package jmind.core.spring;

import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;

/**
 * <p>Title: 获取spring上下文的对象实例</p>
 * <p>Description: 利用spring的BeanFactoryAware，将beanFactory保存在一个单例中</p>
 * <p>Company: letv.com</p>
 * 
    <bean id="serviceLocator" class="jmind.core.spring.SpringBeanFactoryLocator"
        factory-method="getInstance" />
 * 
 * @author 
 */
public class SpringBeanFactoryLocator implements BeanFactoryAware, BeanLocator {

    private static final SpringBeanFactoryLocator SPRINGBEANLOCATOR = new SpringBeanFactoryLocator();

    public <T> T getBean(final Class<T> clazz) {
        return beanFactory.getBean(clazz);
    }

    public boolean containsBean(String name) {
        return beanFactory.containsBean(name);
    }

    /**
    * 根据提供的bean名称得到相应的服务类    
    * @param beanName bean名称    
    */
    @SuppressWarnings("unchecked")
    public <T> T getBean(final String beanName) {
        return (T) beanFactory.getBean(beanName);
    }

    /**
    * 根据提供的bean名称得到对应于指定类型的服务类
    * @param servName bean名称
    * @param clazz 返回的bean类型,若类型不匹配,将抛出异常
    */
    public <T> T getBean(final String beanName, final Class<T> clazz) {
        return beanFactory.getBean(beanName, clazz);
    }

    public static SpringBeanFactoryLocator getInstance() {
        return SPRINGBEANLOCATOR;
    }

    private BeanFactory beanFactory;

    private SpringBeanFactoryLocator() {
    }

    public DefaultListableBeanFactory getBeanFactory() {
        return (DefaultListableBeanFactory) this.beanFactory;
    }

    public void setBeanFactory(final BeanFactory factory) throws BeansException {

        this.beanFactory = factory;

    }

    /**
     * 动态加载bean
     * @see http://wenku.baidu.com/link?url=KEFaIwqStSHzNM99JGlb5CnKoEaYnaTlyVZiAOrTxKtEVvOUmXptJgcZj-JKChJzHtmhq_9PVJi-y7-Q7JLfpBpIWXNrOvX5715XnqTNvlq
     * @param clazz
     */
    public void loadBean(Class<?> clazz) {
        BeanDefinitionBuilder userBeanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        getBeanFactory().registerBeanDefinition(clazz.getName(), userBeanDefinitionBuilder.getRawBeanDefinition());

    }

    public void removeBean(String name) {
        if (beanFactory.containsBean(name)) {
            getBeanFactory().removeBeanDefinition(name);
        }
    }

    public void loadBean(Class<?> clazz, Map<String, Object> props) {
        BeanDefinitionBuilder userBeanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        for (Entry<String, Object> entry : props.entrySet()) {
            userBeanDefinitionBuilder.addPropertyValue(entry.getKey(), entry.getValue());
        }
        // 增加对象
        //  userBeanDefinitionBuilder.addPropertyReference(name, beanName)

        getBeanFactory().registerBeanDefinition(clazz.getName(), userBeanDefinitionBuilder.getRawBeanDefinition());

    }
}
